{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8b8d7b17-af50-42cd-b531-ef61c49c9e61",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the work directory to the imaginaire root.\n",
    "import os, sys, time\n",
    "import pathlib\n",
    "root_dir = pathlib.Path().absolute().parents[2]\n",
    "os.chdir(root_dir)\n",
    "print(f\"Root Directory Path: {root_dir}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b5b9e2f-841c-4815-92e0-0c76ed46da62",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import Python libraries.\n",
    "import numpy as np\n",
    "import torch\n",
    "import k3d\n",
    "import json\n",
    "from collections import OrderedDict\n",
    "# Import imaginaire modules.\n",
    "from projects.nerf.utils import camera, visualize\n",
    "from third_party.colmap.scripts.python.read_write_model import read_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97bedecf-da68-44b1-96cf-580ef7e7f3f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Read the COLMAP data.\n",
    "colmap_path = \"datasets/lego_ds2\"\n",
    "json_fname = f\"{colmap_path}/transforms.json\"\n",
    "with open(json_fname) as file:\n",
    "    meta = json.load(file)\n",
    "center = meta[\"sphere_center\"]\n",
    "radius = meta[\"sphere_radius\"]\n",
    "# Convert camera poses.\n",
    "poses = []\n",
    "for frame in meta[\"frames\"]:\n",
    "    c2w = torch.tensor(frame[\"transform_matrix\"])\n",
    "    c2w[:, 1:3] *= -1\n",
    "    w2c = c2w.inverse()\n",
    "    pose = w2c[:3]  # [3,4]\n",
    "    poses.append(pose)\n",
    "poses = torch.stack(poses, dim=0)\n",
    "print(f\"# images: {len(poses)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2016d20c-1e58-407f-9810-cbe76dc5ccec",
   "metadata": {},
   "outputs": [],
   "source": [
    "vis_depth = 0.2\n",
    "k3d_textures = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7168a09-6654-4660-b140-66b9dfd6f1e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# (optional) visualize the images.\n",
    "# This block can be skipped if we don't want to visualize the image observations.\n",
    "for i, frame in enumerate(meta[\"frames\"]):\n",
    "    image_fname = frame[\"file_path\"]\n",
    "    image_path = f\"{colmap_path}/{image_fname}\"\n",
    "    with open(image_path, \"rb\") as file:\n",
    "        binary = file.read()\n",
    "    # Compute the corresponding image corners in 3D.\n",
    "    pose = poses[i]\n",
    "    corners = torch.tensor([[-0.5, 0.5, 1], [0.5, 0.5, 1], [-0.5, -0.5, 1]])\n",
    "    corners *= vis_depth\n",
    "    corners = camera.cam2world(corners, pose)\n",
    "    puv = [corners[0].tolist(), (corners[1]-corners[0]).tolist(), (corners[2]-corners[0]).tolist()]\n",
    "    k3d_texture = k3d.texture(binary, file_format=\"jpg\", puv=puv)\n",
    "    k3d_textures.append(k3d_texture)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b6cf60ec-fe6a-43ba-9aaf-e3c7afd88208",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Visualize the bounding sphere.\n",
    "json_fname = f\"{colmap_path}/transforms.json\"\n",
    "with open(json_fname) as file:\n",
    "    meta = json.load(file)\n",
    "center = meta[\"sphere_center\"]\n",
    "radius = meta[\"sphere_radius\"]\n",
    "# ------------------------------------------------------------------------------------\n",
    "# These variables can be adjusted to make the bounding sphere fit the region of interest.\n",
    "# The adjusted values can then be set in the config as data.readjust.center and data.readjust.scale\n",
    "readjust_center = np.array([0., 0., 0.])\n",
    "readjust_scale = 1.\n",
    "# ------------------------------------------------------------------------------------\n",
    "center += readjust_center\n",
    "radius *= readjust_scale\n",
    "# Make some points to hallucinate a bounding sphere.\n",
    "sphere_points = np.random.randn(100000, 3)\n",
    "sphere_points = sphere_points / np.linalg.norm(sphere_points, axis=-1, keepdims=True)\n",
    "sphere_points = sphere_points * radius + center"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fdde170b-4546-4617-9162-a9fcb936347d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Visualize with K3D.\n",
    "plot = k3d.plot(name=\"poses\", height=800, camera_rotate_speed=5.0, camera_zoom_speed=3.0, camera_pan_speed=1.0)\n",
    "k3d_objects = visualize.k3d_visualize_pose(poses, vis_depth=vis_depth, xyz_length=0.02, center_size=0.01, xyz_width=0.005, mesh_opacity=0.)\n",
    "for k3d_object in k3d_objects:\n",
    "    plot += k3d_object\n",
    "for k3d_texture in k3d_textures:\n",
    "    plot += k3d_texture\n",
    "plot += k3d.points(sphere_points, color=0x4488ff, point_size=0.01, shader=\"flat\")\n",
    "plot.display()\n",
    "plot.camera_fov = 30.0"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
